package com.core.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;

public class FileUtil {

	public static String readFile(String filePath) {
		File file = new File(filePath);
		if (!file.exists() || file.isDirectory()) {
			return null;
		}

		StringBuffer sb = new StringBuffer();
		try {
			InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
			BufferedReader br = new BufferedReader(isr);
			String temp = br.readLine();
			while (temp != null) {
				sb.append(temp + "\n");
				temp = br.readLine();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	public static boolean writeFile(String filePath, String fileContext) {

		File file = new File(filePath);
		if (!file.exists() || file.isDirectory()) {
			return false;
		}
		try {
			FileOutputStream out = new FileOutputStream(file, false);
			StringBuffer sb = new StringBuffer();
			sb.append(fileContext);
			out.write(sb.toString().getBytes("utf-8"));
			out.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return true;
	}

	public static boolean writeFileAppend(String filePath, String fileContext) {

		File file = new File(filePath);
		if (!file.exists() || file.isDirectory()) {
			return false;
		}
		try {
			FileOutputStream out = new FileOutputStream(file, true);
			StringBuffer sb = new StringBuffer();
			sb.append(fileContext);
			out.write(sb.toString().getBytes("utf-8"));
			out.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return true;
	}

	/**
	 * 对压缩文件进行解压
	 * 
	 * @param filePath
	 * @param descDir
	 * @return
	 */
	public static boolean unWrapZipZipFiles(String filePath, String descDir) {
		long startTime = System.currentTimeMillis();
		try {
			File source = new File(filePath);
			ZipInputStream Zin = new ZipInputStream(new FileInputStream(source));
			BufferedInputStream Bin = new BufferedInputStream(Zin);
			ZipEntry entry;
			try {
				while ((entry = Zin.getNextEntry()) != null) {
					String outPath = (descDir + entry.getName()).replaceAll("\\*", "/");
					File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
					if (!file.exists()) {
						file.mkdirs();
					}
					// 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
					if (new File(outPath).isDirectory()) {
						continue;
					}
					FileOutputStream out = new FileOutputStream(outPath);
					BufferedOutputStream Bout = new BufferedOutputStream(out);
					int b;
					while ((b = Bin.read()) != -1) {
						Bout.write(b);
					}
					Bout.close();
					out.close();
					// System.out.println(file + "解压成功");
				}
				Bin.close();
				Zin.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		long endTime = System.currentTimeMillis();
		// System.out.println("耗费时间： " + (endTime - startTime) + " ms");
		return true;
	}

	public static boolean WrapZipFiles(String fileName, String outFile) {
		int i = 0;
		File souFile = new File(fileName);
		while (!souFile.exists()) {
			return false;
		}

		File[] subFile = souFile.listFiles();// getFiles(souFile);
		ZipOutputStream zos = null;
		byte[] binfo = null;
		int fileSize = 0;
		try {
			zos = new ZipOutputStream(new FileOutputStream(outFile));
			zos.setLevel(2);
			while (i < subFile.length) {
				ZipEntry ze = new ZipEntry(subFile[i].getName());
				zos.putNextEntry(ze);
				if (subFile[i].isFile()) {
					FileInputStream fis = new FileInputStream(subFile[i].getAbsoluteFile());
					fileSize = (int) subFile[i].length();
					binfo = new byte[fileSize];
					fis.read(binfo);
					zos.write(binfo, 0, fileSize);
					fis.close();
					// System.out.println("Add File " +
					// subFile[i].getAbsoluteFile() + " to Zip: " + outFile);
				}
				i++;
			}
			zos.closeEntry();
			zos.flush();
			zos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;

		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			// this.RemoveFile(souFile);
		}

		return true;
	}
	
	public static boolean WrapZipFiles(File[] files, String outFile) {
		int i = 0;

		ZipOutputStream zos = null;
		byte[] binfo = null;
		int fileSize = 0;
		try {
			zos = new ZipOutputStream(new FileOutputStream(outFile));
			zos.setLevel(2);
			while (i < files.length) {
				File souFile = files[i];
				if(!souFile.exists()){
					continue;
				}
				
				ZipEntry ze = new ZipEntry(souFile.getName());
				zos.putNextEntry(ze);
				if (souFile.isFile()) {
					FileInputStream fis = new FileInputStream(souFile.getAbsoluteFile());
					fileSize = (int) souFile.length();
					binfo = new byte[fileSize];
					fis.read(binfo);
					zos.write(binfo, 0, fileSize);
					fis.close();
				}
				i++;
			}
			zos.closeEntry();
			zos.flush();
			zos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;

		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			// this.RemoveFile(souFile);
		}

		return true;
	}
	
	public static boolean WrapZipFilesByAnt(String fileName, String outFile) {
		File srcdir = new File(fileName);
		if (!srcdir.exists()) {
			return false;
		}
		
		File zipFile = new File(outFile);

		Project prj = new Project();
		Zip zip = new Zip();
		zip.setProject(prj);
		zip.setDestFile(zipFile);
		FileSet fileSet = new FileSet();
		fileSet.setProject(prj);
		fileSet.setDir(srcdir);
		// fileSet.setIncludes("**/*.java"); //包括哪些文件或文件夹
		// eg:zip.setIncludes("*.java");
		// fileSet.setExcludes(...); //排除哪些文件或文件夹
		zip.addFileset(fileSet);
		zip.execute();
		return true;
	}

	public static boolean WrapZipFilesByAnt(File[] files, String outFile) {

			File zipFile = new File(outFile);

			Project prj = new Project();
			Zip zip = new Zip();
			zip.setProject(prj);
			zip.setDestFile(zipFile);
			
			int i = 0;
			while (i < files.length) {
				File srcdir = files[i];
				if (!srcdir.exists()) {
					return false;
				}
			
				FileSet fileSet = new FileSet();
				fileSet.setProject(prj);
				fileSet.setDir(srcdir);
				// fileSet.setIncludes("**/*.java"); //包括哪些文件或文件夹
				// eg:zip.setIncludes("*.java");
				// fileSet.setExcludes(...); //排除哪些文件或文件夹
				zip.addFileset(fileSet);
				i++;
			}
			zip.execute();
		return true;
	}
	
	public static String deleteFiles(String folderPath) throws IllegalStateException {
		if (!StringUtils.isEmpty(folderPath)) {
			File targetFile = new File(folderPath);
			deleteDir(targetFile);
		}
		return null;
	}

	private static boolean deleteDir(File dir) {
		if (dir.isDirectory()) {
			String[] children = dir.list();
			// 递归删除目录中的子目录下
			for (int i = 0; i < children.length; i++) {
				boolean success = deleteDir(new File(dir, children[i]));
				if (!success) {
					return false;
				}
			}
		}
		// 目录此时为空，可以删除
		return dir.delete();
	}

	public static boolean Move(File srcFile, String destPath) {
		// Destination directory
		File dir = new File(destPath);

		if (!dir.exists()) {
			dir.mkdirs();
		}

		// Move file to new directory
		boolean success = srcFile.renameTo(new File(dir, srcFile.getName()));

		return success;
	}

	public static boolean Move(File srcFile, String destPath, String newFileName) {
		// Destination directory
		File dir = new File(destPath);

		if (!dir.exists()) {
			dir.mkdirs();
		}

		// Move file to new directory
		boolean success = srcFile.renameTo(new File(dir, newFileName));

		return success;
	}

	public static boolean Move(String srcFile, String destPath) {
		// File (or directory) to be moved
		File file = new File(srcFile);

		// Destination directory
		File dir = new File(destPath);

		if (!dir.exists()) {
			dir.mkdirs();
		}

		// Move file to new directory
		boolean success = file.renameTo(new File(dir, file.getName()));

		return success;
	}

	public static boolean Move(String srcFile, String destPath, String newFileName) {
		// File (or directory) to be moved
		File file = new File(srcFile);

		// Destination directory
		File dir = new File(destPath);

		if (!dir.exists()) {
			dir.mkdirs();
		}

		// Move file to new directory
		boolean success = file.renameTo(new File(dir, newFileName));

		return success;
	}

	public static void Copy(String oldPath, String newPath) {
		try {
			int bytesum = 0;
			int byteread = 0;
			File oldfile = new File(oldPath);
			if (oldfile.exists()) {
				InputStream inStream = new FileInputStream(oldPath);
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				int length;
				while ((byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread;
					System.out.println(bytesum);
					fs.write(buffer, 0, byteread);
				}
				inStream.close();
			}
		} catch (Exception e) {
			System.out.println("error  ");
			e.printStackTrace();
		}
	}

	public static void Copy(File oldfile, String newPath) {
		try {
			int bytesum = 0;
			int byteread = 0;
			// File oldfile = new File(oldPath);
			if (oldfile.exists()) {
				InputStream inStream = new FileInputStream(oldfile);
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				while ((byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread;
					System.out.println(bytesum);
					fs.write(buffer, 0, byteread);
				}
				inStream.close();
			}
		} catch (Exception e) {
			System.out.println("error  ");
			e.printStackTrace();
		}
	}
	
	public static void crateHTML(ServletContext context, Map<String, Object> data, String templatePath, String templateName, String targetHtmlPath,
			String targetHtmlName) {
		Configuration freemarkerCfg = new Configuration();
		// 加载模版文件的路径
		freemarkerCfg.setServletContextForTemplateLoading(context, templatePath.concat("/"));
		freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
		try {
			// 指定模版路径
			freemarker.template.Template template = freemarkerCfg.getTemplate(templateName, "UTF-8");
			template.setEncoding("UTF-8");
			
			File dir = new File(context.getRealPath(targetHtmlPath));
			if (!dir.exists()) {
				dir.mkdirs();
			}
			
			// 静态页面路径
			String htmlPath = context.getRealPath(targetHtmlPath).concat("/").concat(targetHtmlName);
			//判断有没有，有先删除
	        FileUtil.deleteFiles(htmlPath);
			
			File htmlFile = new File(htmlPath);
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
			// 处理模版并开始输出静态页面
			template.process(data, out);
			out.flush();
			out.close();

		} catch (Exception e) {
			System.out.println("error 生成静态网页出错 ");
			e.printStackTrace();
		}
	}
	
	public static void crateHTML( Map<String, Object> data, String templatePath, String templateName, String targetHtmlPath,
			String targetHtmlName) {

        Configuration configuration = new Configuration();  
        try{
		
	        configuration.setDirectoryForTemplateLoading(new File(templatePath));  
	        
	        configuration.setObjectWrapper(new DefaultObjectWrapper());  
	        configuration.setDefaultEncoding("UTF-8");   //这个一定要设置，不然在生成的页面中 会乱码  
        
	        //获取或创建一个模版。  
	        freemarker.template.Template staticTemp = configuration.getTemplate("/".concat(templateName));  
	        
	        File dir = new File(targetHtmlPath);
			if (!dir.exists()) {
				dir.mkdirs();
			}

	        String staticFilePath = targetHtmlPath.concat("/").concat(targetHtmlName);

	        //判断有没有，有先删除
	        FileUtil.deleteFiles(staticFilePath);
	        Writer writer  = new OutputStreamWriter(new FileOutputStream(staticFilePath),"UTF-8");  
	        staticTemp.process(data, writer);
	        writer.close();
		}catch(Exception e){
			System.out.println("error 生成静态网页出错 ");
			e.printStackTrace();
		}
	}

}
